package com.zb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.db.Page;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.constant.CodeConstant;
import com.zb.entity.*;
import com.zb.mapper.ZjSmsSendLogMapper;
import com.zb.result.PageUtil;
import com.zb.service.*;
import com.zb.utils.TransactionUtil;
import com.zb.utils.ZbNumberUtil;
import com.zb.vo.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 商家短信发送记录表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2024-03-23
 */
@Service
public class ZjSmsSendLogServiceImpl extends ServiceImpl<ZjSmsSendLogMapper, ZjSmsSendLog> implements ZjSmsSendLogService {
    private static final Logger logger = LoggerFactory.getLogger(ZjSmsSendLogServiceImpl.class);
    @Resource
    private ZjSmsSendLogMapper smsSendLogMapper;
    @Resource
    private ZjSmsSendLog02Service smsSendLog02Service;
    @Resource
    private ZjSmsSendLog03Service smsSendLog03Service;
    @Resource
    private ZjSmsSendLog04Service smsSendLog04Service;
    @Resource
    private ZjSmsSendLog05Service smsSendLog05Service;
    @Resource
    private PlatformTransactionManager platformTransactionManager;
    @Resource(name = "asyncServiceExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override
    public void saveSuccess(List<SmsSendLogVo> logVos) {
        if (CollectionUtil.isEmpty(logVos)) {
            return;
        }
        this.save(logVos, true);
    }


    @Override
    public void saveFailt(List<SmsSendLogVo> logVos) {
        this.save(logVos, false);
    }

    private void save(List<SmsSendLogVo> logVos, boolean success) {
        if (CollectionUtil.isEmpty(logVos)) {
            return;
        }
        threadPoolTaskExecutor.execute(() -> {
            TransactionStatus status = platformTransactionManager.getTransaction(TransactionUtil.transactionDefinition());
            List<ZjSmsSendLog> logs = new ArrayList<>();
            List<ZjSmsSendLog02> log02s = new ArrayList<>();
            List<ZjSmsSendLog03> log03s = new ArrayList<>();
            List<ZjSmsSendLog04> log04s = new ArrayList<>();
            List<ZjSmsSendLog05> log05s = new ArrayList<>();
            ZjSmsSendLog log = null;
            for (SmsSendLogVo vo : logVos) {
                log = new ZjSmsSendLog();
                BeanUtil.copyProperties(vo, log);
                log.setSuccess(success);

                switch (CodeConstant.tableType(vo.getId())) {
                    case 0:
                        logs.add(log);
                        continue;
                    case 1:
                        log02s.add(new ZjSmsSendLog02(log));
                        continue;
                    case 2:
                        log03s.add(new ZjSmsSendLog03(log));
                        continue;
                    case 3:
                        log04s.add(new ZjSmsSendLog04(log));
                        continue;
                    case 4:
                        log05s.add(new ZjSmsSendLog05(log));
                }
            }
            try {
                if (CollectionUtil.isNotEmpty(logs)) this.saveBatch(logs);
                if (CollectionUtil.isNotEmpty(log02s)) smsSendLog02Service.saveBatch(log02s);
                if (CollectionUtil.isNotEmpty(log03s)) smsSendLog03Service.saveBatch(log03s);
                if (CollectionUtil.isNotEmpty(log04s)) smsSendLog04Service.saveBatch(log04s);
                if (CollectionUtil.isNotEmpty(log05s)) smsSendLog05Service.saveBatch(log05s);
                platformTransactionManager.commit(status);
            }catch (Exception e) {
                logger.error("添加短信发送日志失败：{}", e.getMessage());
                e.printStackTrace();
                platformTransactionManager.rollback(status);
            }
        });
    }

    // 获取短信发送记录列表
    @Override
    public Map<String, Object> getList(Long custAccId, SmsSendLogListSearchVo searchVo) {
        PageUtil.setPageLimit(searchVo);
        long count = smsSendLogMapper.getListCount(custAccId, searchVo);
        if (count <= 0) {
            return PageUtil.pageList(searchVo.getPage(), searchVo.getLimit(), count, new ArrayList<>());
        }
        List<ZjSmsSendLog> sendLogList = smsSendLogMapper.getList(custAccId, searchVo);
        return PageUtil.pageList(searchVo.getPage(), searchVo.getLimit(), count, sendLogList.stream().map(log -> {
            SmsSendLogListVo vo = new SmsSendLogListVo();
            BeanUtil.copyProperties(log, vo);
            vo.setSmsContent(log.getReceiveContent());
            vo.setCreateTime(log.getGmtCreate());
            return vo;
        }).toList());
    }

    // 根据短信ID获取发送短信详情
    @Override
    public SmsSendLogListVo getDetail(Long id) {
        ZjSmsSendLog log = smsSendLogMapper.getById(id);
        Assert.notNull(log, "发送短信记录参数[ " + id + " ]的数据不存在");
        SmsSendLogListVo vo = new SmsSendLogListVo();
        BeanUtil.copyProperties(log, vo);
        vo.setSmsContent(log.getReceiveContent());
        return vo;
    }

    // 获取短信发送数量列表
    @Override
    public Map<String, Object> getSendSmsCountList(Long custAccId, SendSmsCountListSearchVo searchVo) {
        PageUtil.setPageLimit(searchVo);
        long count = smsSendLogMapper.getSendSmsCountListCount(custAccId, searchVo);
        if (count <= 0) {
            return PageUtil.pageList(searchVo.getPage(), searchVo.getLimit(), count, new ArrayList<>());
        }
        List<SendSmsCountListVo> voList = smsSendLogMapper.getSendSmsCountList(custAccId, searchVo);
        voList.forEach(t -> {
            t.setSendSuccessRate(ZbNumberUtil.getPercentage(t.getSendSuccessCount(), t.getSendTotalCount()));
        });
        return PageUtil.pageList(searchVo.getPage(), searchVo.getLimit(), count, voList);
    }


}
